(use gauche.net)
(use gauche.selector)

(define (echo-server port cont)
  (let ((selector (make <selector>))
        (server   (make-server-socket 'inet port :reuse-addr? #t)))
    (define (accept-handler sock flag)
      (let* ((client (socket-accept server))
             (output (socket-output-port client)))
        (selector-add! selector
                       (socket-input-port client :buffering #f)
                       (lambda (input flag)
                         (echo client input output))
                       '(r))))

    (define (echo client input output)
      (let ((str (read-block 4096 input)))
        (if (eof-object? str)
            (begin (selector-delete! selector input #f #f)
                   (socket-close client))
            (begin (display "wait 3sec.\n")
                   (flush)
                   (sys-sleep 2)
                   (display str output)
                   (flush output)
                   (display str)
                   (flush)))))

   (set-signal-handler! SIGTERM (lambda (sig) (socket-close server) (socket-shutdown server) (cont)))
   (set-signal-handler! SIGINT  (lambda (sig) (socket-close server) (socket-shutdown server) (cont)))
   (selector-add! selector
                  (socket-fd server)
                  accept-handler
                  '(r))
   (do () (#f) (selector-select selector))))

(call/cc (lambda (cont)
           (echo-server 60000 cont)))
